﻿using CutShuFa.AutoAction;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CutShuFa
{
    public partial class AutoActionForm : Form
    {
        AutoActionData data;
        Dictionary<string, Type> ActionDic;
        List<AutoProcess> autoProcesses;
        AutoProcess curProcess;
        string proecssFile = "auto_process.json";
        public AutoActionForm()
        {
            InitializeComponent();
            ActionDic = GetAllAutoAction();
            cb_actions.Items.AddRange(ActionDic.Keys.ToArray());
            cb_actions.SelectedIndex = 0;
            autoProcesses = LoadAutoProcesses();
            cb_process.Items.AddRange(autoProcesses.ToArray());
            if(autoProcesses.Count > 0) cb_process.SelectedIndex = 0;
        }

        public List<AutoProcess> LoadAutoProcesses()
        {
            List<AutoProcess> autoProcesses = new List<AutoProcess>();
            if (File.Exists(proecssFile))
            {
                string json = File.ReadAllText(proecssFile);
                if (json.Length > 0){
                    var ams = JsonSerializer.Deserialize<List<AutoProcessModel>>(File.ReadAllText(proecssFile));
                    foreach (var item in ams)
                    {
                        AutoProcess autoProcess = new AutoProcess(item.ProcessName);
                        foreach (var action in item.Actions)
                        {
                            IAutoAction actionModel = Activator.CreateInstance(ActionDic[action.ActionName]) as IAutoAction;
                            actionModel.Parameters = action.Parameters;
                            autoProcess.Actions.Add(actionModel);
                        }
                        autoProcesses.Add(autoProcess);
                    }
                }
                return autoProcesses;
            }
            return new List<AutoProcess>();
        }
        /// <summary>
        /// 获取接口IAutoAction的全部实现类
        /// </summary>
        public Dictionary<string, Type> GetAllAutoAction()
        {
            var t = typeof(IAutoAction);
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            List<Type> actionTypes = new List<Type>();
            foreach (var assembly in assemblies)
            {
                var types = assembly.GetTypes();
                foreach (var type in types)
                {
                    if (t.IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract)
                    {
                        actionTypes.Add(type);
                    }
                }
            }
            Dictionary<string, Type> AutoActionTypeDic = new Dictionary<string, Type>();
            foreach (var item in actionTypes)
            {
                var itm = Activator.CreateInstance(item) as IAutoAction;
                AutoActionTypeDic.Add(itm.ActionName, item);
            }
            return AutoActionTypeDic;
        }

        private void bt_processAllPics_Click(object sender, EventArgs e)
        {
            var autoProcesses = GetCurProcess();
            if (lb_pics.Items.Count == 0 || autoProcesses == null)
            {
                return;
            }
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            //设置显示的标题
            folderBrowserDialog.Description = "请选择保存图片文件夹";
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                string savePath = folderBrowserDialog.SelectedPath;
                foreach (string fn in lb_pics.Items)
                {
                    var data = new AutoActionData(fn);
                    foreach (var action in curProcess.Actions)
                    {
                        ActionRun(action, data);
                    }
                    string save_fn = Path.Combine(savePath, Path.GetFileName(fn));
                    data.Save(save_fn);
                }
            }
        }

        private void ActionRun(IAutoAction action, AutoActionData data)
        {
            try
            {
                action.Run(data);
            }
            catch (Exception ex)
            {
                lb_msg.Text = ex.Message;
            }
        }

        private void bt_addAction_Click(object sender, EventArgs e)
        {
            if (cb_actions.SelectedItem != null)
            {
                string actionName = (string)cb_actions.SelectedItem;
                Type action = ActionDic[actionName];
                IAutoAction autoAction = (IAutoAction)Activator.CreateInstance(action);
                addActionControl(autoAction);
            }
        }

        private void addActionControl(IAutoAction action)
        {
            AutoActionParameterControl actionControl = new AutoActionParameterControl();
            actionControl.Init(action);
            actionControl.UpClick += upClick;
            actionControl.DownClick += downClick;
            actionControl.DelClick += delClick;
            actionControl.RunClick += runClick;
            actionControl.PerformLayout();
            actionsPanel.Controls.Add(actionControl);
            actionsPanel.PerformLayout();
        }
        private void upClick(object sender, EventArgs e)
        {
            AutoActionParameterControl actionControl = sender as AutoActionParameterControl;
            int index = actionsPanel.Controls.IndexOf(actionControl);
            if (index > 0)
            {
                actionsPanel.Controls.SetChildIndex(actionControl, index - 1);
            }
        }

        private void downClick(object sender, EventArgs e)
        {
            AutoActionParameterControl actionControl = sender as AutoActionParameterControl;
            int index = actionsPanel.Controls.IndexOf(actionControl);
            if (index < actionsPanel.Controls.Count - 1)
            {
                actionsPanel.Controls.SetChildIndex(actionControl, index + 1);
            }
        }

        private void delClick(object sender, EventArgs e)
        {
            AutoActionParameterControl actionControl = sender as AutoActionParameterControl;
            actionsPanel.Controls.Remove(actionControl);
        }

        private void runClick(object sender, EventArgs e)
        {
            AutoActionParameterControl actionControl = sender as AutoActionParameterControl;
            IAutoAction action = actionControl.GetAction();
            ActionRun(action, data);
            //tabControl1.SelectedIndex
            pic_src.Image = data.SrcBitmap;
            pic_tmp.Image = data.TmpBitmap;
            pic_gray.Image = data.GrayBitmap;
        }

        private void bt_loadProcess_Click(object sender, EventArgs e)
        {
            if (cb_process.SelectedItem != null)
            {
                curProcess = (AutoProcess)cb_process.SelectedItem;
                tb_processName.Text = curProcess.ProcessName;
                actionsPanel.Controls.Clear();
                foreach (var action in curProcess.Actions)
                {
                    addActionControl(action);
                }
            }
        }

        private void bt_runProcess_Click(object sender, EventArgs e)
        {
            AutoProcess autoProcess = GetCurProcess();
            if (autoProcess == null || data == null)
            {
                return;
            }
            foreach (var action in autoProcess.Actions)
            {
                ActionRun(action, data);
            }
            pic_src.Image = data.SrcBitmap;
            pic_tmp.Image = data.TmpBitmap;
            pic_gray.Image = data.GrayBitmap;
        }

        AutoProcess GetCurProcess()
        {
            if (tb_processName.Text.Trim() == "" || actionsPanel.Controls.Count == 0)
            {
                return null;
            }
            if (curProcess == null)
            {
                AutoProcess autoProcess = new AutoProcess(tb_processName.Text);
                foreach (AutoActionParameterControl item in actionsPanel.Controls)
                {
                    autoProcess.Actions.Add(item.GetAction());
                }
                return autoProcess;
            }
            else
            {
                curProcess.ProcessName = tb_processName.Text;
                curProcess.Actions.Clear();
                foreach (AutoActionParameterControl item in actionsPanel.Controls)
                {
                    curProcess.Actions.Add(item.GetAction());
                }
                return curProcess;
            }
        }

        private void bt_saveProcess_Click(object sender, EventArgs e)
        {
            AutoProcess autoProcess = GetCurProcess();
            if (autoProcess == null)
            {
                return;
            }
            if (curProcess == null)
            {
                autoProcesses.Add(autoProcess);
                cb_process.Items.Add(autoProcess);
                cb_process.SelectedItem = autoProcess;
                string json = JsonSerializer.Serialize(autoProcesses);
                File.WriteAllText(proecssFile, json);
            }
            else
            {
                string json = JsonSerializer.Serialize(autoProcesses);
                File.WriteAllText(proecssFile, json);
            }
        }

        private void bt_addPics_Click(object sender, EventArgs e)
        {
            // 打开对话框，选择图片，添加图片
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = true;
            openFileDialog.Filter = "图片文件|*.jpg;*.png;*.jpeg;*.bmp";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                foreach (string filePath in openFileDialog.FileNames)
                {
                    lb_pics.Items.Add(filePath);
                }
            }
        }

        private void bt_addProcess_Click(object sender, EventArgs e)
        {
            curProcess = null;
            tb_processName.Text = "";
            actionsPanel.Controls.Clear();
        }

        private void lb_pics_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lb_pics.SelectedItem != null)
            {
                string fn = lb_pics.SelectedItem.ToString();
                data = new AutoActionData(fn);
                pic_src.Image = data.SrcBitmap;
                pic_tmp.Image = data.TmpBitmap;
                pic_gray.Image = data.GrayBitmap;
            }
        }

        private void AutoActionForm_Load(object sender, EventArgs e)
        {

        }

    }
}
